//密码加密
/* eslint-disable no-unused-expressions */
/* eslint-disable eqeqeq */
/* eslint-disable no-undef */
/*eslint-disable*/
// tslint: disable 该行以下的内容都不再检查
// @ts-nocheck # 忽略全文
// import { appUrl } from '@src/utils/baseVariable'
import { sm3_encrypt, sm4_encrypt_ecb, addH16ZeroTwo, sm3_byte, toTwoHex } from './sm'
import { CryptoJS, SM2Cipher } from './sm2'
// import { queryLogin } from '@api/loginApi'
// import { transCatchInfo } from '../translator'
const DigestAuth = {
	// firstHeader: '',
	// qop: '',
	realm: '',
	// nonce: '',
	// nc: '',
	// algorithm: '',
	username: '',
	loginname: '',
	password: '',
	header: {},
	//digestAuthLogin: function (data, config, loginSuccess, loginError) {
	// queryLogin(data, config).then(
	// 	(res) => {
	// 		loginSuccess(res)
	// 	},
	// 	(res) => {
	// 		let response = res.response
	// 		let wwwAuthenticate = response.headers['www-authenticate']
	// 		//判断 nonce是否过期
	// 		if (wwwAuthenticate && wwwAuthenticate.indexOf('stale="true"') !== -1) {
	// 			DigestAuth.sendAgain(response, data, config, loginSuccess, loginError)
	// 		} else {
	// 			let _data = transCatchInfo(response.data)
	// 			loginError(_data)
	// 		}
	// 	}
	// )
	//},
	// sendAgain: function (response, data, config, loginSuccess, loginError) {
	// 	let status = response.status
	// 	let wwwAuthenticate = response.headers['www-authenticate']
	// 	if (response && status == 401) {
	// 		var firstHeader = wwwAuthenticate
	// 		this.qop = firstHeader.split('qop="')[1].split('"')[0]
	// 		this.realm = firstHeader.split('realm="')[1].split('"')[0]
	// 		DigestAuth.realm = this.realm
	// 		this.nonce = firstHeader.split('nonce="')[1].split('"')[0]
	// 		this.algorithm = firstHeader.split('algorithm="')[1].split('"')[0]
	// 		this.username = firstHeader.split('moid="')[1].split('"')[0]
	// 		this.snonce = firstHeader.split('snonce="')[1] ? firstHeader.split('snonce="')[1].split('"')[0] : null
	// 		var method = config.type
	// 		config.url = config.url.replace('&check=1', '')
	// 		var url = appUrl + config.url
	// 		config.headers = DigestAuth.makeHeader(
	// 			method,
	// 			url,
	// 			this.qop,
	// 			this.realm,
	// 			this.nonce,
	// 			this.algorithm,
	// 			this.snonce
	// 		)
	// 		DigestAuth.header = config.headers
	// 		DigestAuth.digestAuthLogin(data, config, loginSuccess, loginError)
	// 	}
	// },
	makeHeader: function (
		method: string,
		uri: string,
		qop: string,
		realm: string,
		nonce: string,
		algorithm: string,
		snonce: any
	) {
		var header = {}
		var ha1 = sm3_encrypt(Utf8Encode(DigestAuth.username + ':' + realm + ':' + DigestAuth.password))
		var ha2 = sm3_encrypt(method + ':' + uri)
		var nc = (Math.random() * 10000000).toFixed(0)
		// @ts-ignore: Unreachable code error
		var guid = new GUID()
		var cnonce = guid.newGUID()
		var response = sm3_encrypt(ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2)
		var sm = null
		if (snonce) {
			sm = this.getSMEncrypt(DigestAuth.password, snonce)
		}
		var auth = [
			"username*=UTF-8''" + encodeURI(DigestAuth.username),
			'realm="' + realm + '"',
			'nonce="' + nonce + '"',
			'uri="' + uri + '"',
			'qop=' + qop,
			'cnonce="' + cnonce + '"',
			'algorithm="' + algorithm + '"',
			'loginname="' + DigestAuth.loginname + '"',
			'response="' + response + '"',
			'nc=' + nc,
		].join(',')
		// @ts-ignore: Unreachable code error
		header['Authorization'] = 'Digest_SM3 ' + auth
		if (sm) {
			// @ts-ignore: Unreachable code error
			header['SM'] = sm
		}
		return header
	},
	// 第一次登录时
	makeDigestAuthHeader: function () {
		var header = {}
		var auth = ["username*=UTF-8''" + encodeURI(DigestAuth.username)].join(',')
		header['Authorization'] = 'Digest_SM3 ' + auth
		return header
	},
	makePassword: function (oldpassword: string, newpassword: any) {
		var p_username = DigestAuth.username
		var p_realm = DigestAuth.realm
		// @ts-ignore: Unreachable code error
		var guid = new GUID()
		var knonce = guid.newGUID()
		var ha1 = sm3_encrypt(Utf8Encode(p_username + ':' + p_realm + ':' + oldpassword)).toUpperCase()
		var mkey = sm3_encrypt(ha1 + ':' + knonce).toUpperCase()
		var hkey = sm3_encrypt(mkey + ':' + knonce).toUpperCase()
		var get_sm4_encrypt_ecb = sm4_encrypt_ecb(newpassword, mkey.substring(0, 32))
		var ciphertext = get_sm4_encrypt_ecb ? get_sm4_encrypt_ecb.res_ciphertext.toUpperCase() : ''
		var hkey_p = new Array(64)
		var ipad = new Array(64)
		var opad = new Array(64)

		var index = 0
		for (var i = 0; i < hkey_p.length; i++) {
			hkey_p[i] = 0
		}
		index = 0
		for (var i = 0; i < hkey.length; i = i + 2) {
			hkey_p[index++] = parseInt(hkey.substring(i, i + 2), 16)
		}

		var ipadStr = ''
		var opadStr = ''
		var index1 = 0
		for (var i = 0; i < index; i++) {
			index1++
			ipad[i] = hkey_p[i] ^ 0x36
			opad[i] = hkey_p[i] ^ 0x5c

			ipadStr += addH16ZeroTwo(ipad[i].toString(16))
			opadStr += addH16ZeroTwo(opad[i].toString(16))
		}

		for (var i = index1; i < 64; i++) {
			ipad[i] = 0x36
			opad[i] = 0x5c
			ipadStr += addH16ZeroTwo(ipad[i].toString(16))
			opadStr += addH16ZeroTwo(opad[i].toString(16))
		}
		var temp = ipadStr + ciphertext
		temp = opadStr + sm3_byte(toTwoHex(temp)).toUpperCase()
		var hmac = sm3_byte(toTwoHex(temp)).toUpperCase()
		return { knonce: knonce, ciphertext: ciphertext, hmac: hmac }
	},
	makeSM4Encrypt: function (pwd: any) {
		var guid = new GUID()
		var knonce = guid.newGUID()
		var mkey = sm3_encrypt(knonce).toUpperCase()
		var get_sm4_encrypt_ecb = sm4_encrypt_ecb(pwd, mkey.substring(0, 32))
		var ciphertext = get_sm4_encrypt_ecb ? get_sm4_encrypt_ecb.res_ciphertext.toUpperCase() : ''
		return { knonce: knonce, ciphertext: ciphertext, mkey: btoa(mkey.substring(0, 32)) }
	},
	getSMEncrypt: function (pwd: any, snonce: any) {
		var publkey = snonce
		// @ts-ignore: Unreachable code error
		var msgData = CryptoJS.enc.Utf8.parse(pwd)
		if (publkey.length > 64 * 2) {
			publkey = publkey.substr(publkey.length - 64 * 2)
		}
		var xHex = publkey.substr(0, 64)
		var yHex = publkey.substr(64)
		var cipherMode = '1' //C1C3C2
		var cipher = new SM2Cipher(cipherMode)
		var userKey = cipher.CreatePoint(xHex, yHex)
		msgData = cipher.GetWords(msgData.toString())
		var encryptData = cipher.Encrypt(userKey, msgData)
		return encryptData
	},
}
function GUID() {
	let date = new Date() /* 判断是否初始化过，如果初始化过以下代码，则以下代码将不再执行，实际中只执行一次 */
	if (typeof GUID.prototype.newGUID != 'function') {
		/* 生成GUID码 */
		GUID.prototype.newGUID = function () {
			date = new Date()
			var guidStr = ''
			var sexadecimalDate = this.hexadecimal(this.getGUIDDate(), 16)
			var sexadecimalTime = this.hexadecimal(this.getGUIDTime(), 16)
			for (var i = 0; i < 9; i++) {
				guidStr += Math.floor(Math.random() * 16).toString(16)
			}
			guidStr += sexadecimalDate
			guidStr += sexadecimalTime
			while (guidStr.length < 32) {
				guidStr += Math.floor(Math.random() * 16).toString(16)
			}
			return this.formatGUID(guidStr)
		}
		/* * 功能：获取当前日期的GUID格式，即8位数的日期：19700101 * 返回值：返回GUID日期格式的字条串 */
		GUID.prototype.getGUIDDate = function () {
			return date.getFullYear() + this.addZero(date.getMonth() + 1) + this.addZero(date.getDay())
		}
		/* * 功能：获取当前时间的GUID格式，即8位数的时间，包括毫秒，毫秒为2位数：12300933 * 返回值：返回GUID日期格式的字条串 */
		GUID.prototype.getGUIDTime = function () {
			return (
				this.addZero(date.getHours()) +
				this.addZero(date.getMinutes()) +
				this.addZero(date.getSeconds()) +
				this.addZero(date.getMilliseconds() / 10)
			)
		}
		/* * 功能: 为一位数的正整数前面添加0，如果是可以转成非NaN数字的字符串也可以实现 * 参数: 参数表示准备再前面添加0的数字或可以转换成数字的字符串 * 返回值: 如果符合条件，返回添加0后的字条串类型，否则返回自身的字符串 */
		GUID.prototype.addZero = function (num: any) {
			if (Number(num).toString() != 'NaN' && num >= 0 && num < 10) {
				return '0' + Math.floor(num)
			} else {
				return num.toString()
			}
		}
		/*  * 功能：将y进制的数值，转换为x进制的数值 * 参数：第1个参数表示欲转换的数值；第2个参数表示欲转换的进制；第3个参数可选，表示当前的进制数，如不写则为10 * 返回值：返回转换后的字符串 */ GUID.prototype.hexadecimal =
			function (num: { toString: () => string }, x: number | undefined, y: number | undefined) {
				if (y != undefined) {
					return parseInt(num.toString(), y).toString(x)
				} else {
					return parseInt(num.toString()).toString(x)
				}
			}
		/* * 功能：格式化32位的字符串为GUID模式的字符串 * 参数：第1个参数表示32位的字符串 * 返回值：标准GUID格式的字符串 */
		GUID.prototype.formatGUID = function (guidStr: string) {
			var str1 = guidStr.slice(0, 8) + '',
				str2 = guidStr.slice(8, 12) + '',
				str3 = guidStr.slice(12, 16) + '',
				str4 = guidStr.slice(16, 20) + '',
				str5 = guidStr.slice(20)
			return str1 + str2 + str3 + str4 + str5
		}
	}
}

function Utf8Encode(string: string) {
	var utftext = ''
	for (var n = 0; n < string.length; n++) {
		var c = string.charCodeAt(n)
		if (c < 128) {
			utftext += String.fromCharCode(c)
		} else if (c > 127 && c < 2048) {
			utftext += String.fromCharCode((c >> 6) | 192)
			utftext += String.fromCharCode((c & 63) | 128)
		} else {
			utftext += String.fromCharCode((c >> 12) | 224)
			utftext += String.fromCharCode(((c >> 6) & 63) | 128)
			utftext += String.fromCharCode((c & 63) | 128)
		}
	}
	return utftext
}
export { DigestAuth }
